﻿using PIMS.Base;
using PIMS.DBModel;
using PIMS.Interface;
using PIMS.WorkPlugin.ORM;
using PIMS.WorkPlugin.Util;
using PIMS.XmlModel;
using PIMS_Interface.Interface;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Web;

namespace PIMS.WorkPlugin
{
    public class KE23015_PackerHandle : IPLCSignalHandle, IDisposable
    {
        private IDebugMsg debug = null;
        ICommunication plc = null;
        ILog4net log = null;
        int plcIndex = -1;
        PIMSConfigX config = null;
        bool heartBit = false;
        string oldMsg = "";
        string plant = "";
        string sPack = "";
        string sLen = "";

        private PLCSignalHandlePlus x1 = null;
        private PLCSignalHandlePlus x2 = null;
        private BackgroundWorker bgw1 = null;


        CancellationTokenSource cancelTokenSource = new CancellationTokenSource();
        bool alive = false;

        #region Packer实现日志分组功能
        private void DebugMsg(string Msg, InfoLevel level = InfoLevel.info)
        {
            debug.DebugMsg(Msg, LogGroup.packer, level);
        }

        private void LogInfo(string message)
        {
            log.Info(message, LogGroup.packer, plcIndex + 1);
        }

        private void LogError(string message)
        {
            log.Error(message, LogGroup.packer, plcIndex + 1);
        }

        private void LogError(string message, Exception ex)
        {
            log.Error(message, LogGroup.packer, plcIndex + 1, ex);
        }
        #endregion

        /// <summary>
        /// PIMS主程序自动反射加载
        /// </summary>
        /// <param name="plc"></param>
        /// <param name="plcIndex"></param>
        /// <param name="debugMsg"></param>
        /// <param name="log4net"></param>
        public void Init(ICommunication plc, int plcIndex, IDebugMsg debugMsg, ILog4net log4net, PIMSConfigX pimsConfig)
        {
            this.plc = plc;
            sPack = plc.GetDeviceName().Replace("二包", "");
            if (sPack.Equals("1"))
            {
                sLen = "4";
            }
            else if(sPack.Equals("5"))
            {
                sLen = "5";
            }
            this.plcIndex = plcIndex;
            this.debug = debugMsg;
            this.log = log4net;
            this.config = pimsConfig;

            this.plant = pimsConfig.GetAppValueByKey("plant");
            x1 = new PLCSignalHandlePlus(Packer.包装完成标志, EventId.包装完成, debug, this.log); //码垛完成1
            x2 = new PLCSignalHandlePlus(Packer.请求新批次信息标志, EventId.请求新批次信息, debug, this.log); //码垛完成1
            if (!x1.EventBindOk)
            {
                //给输入信号绑定事件
                x1.msgHandler += new PLCSignalHandlePlus.MsgHandler(MyEventHandle);
                x2.msgHandler += new PLCSignalHandlePlus.MsgHandler(MyEventHandle);
            }
                (new System.Threading.Tasks.Task(Thread_CommicationPLC, cancelTokenSource.Token)).Start();

            DebugMsg(String.Format("KE24004_PackerHandle{0} 挂载成功！", this.plcIndex));
            LogInfo(String.Format("KE24004_PackerHandle{0} 挂载成功！", this.plcIndex));
        }

        public void Dispose()
        {
            try
            {
                cancelTokenSource.Cancel();
            }
            catch
            {
            }
        }

        private void Thread_CommicationPLC()
        {
            while (!cancelTokenSource.IsCancellationRequested)
            {
                try
                {
                    if (plc.IsConnected)
                    {
                        if (!alive)
                        {
                            alive = true;
                            this.DebugMsg(plc.GetDeviceName() + "连接成功！", InfoLevel.info);
                            this.LogInfo(plc.GetDeviceName() + "连接成功！");
                        }
                        HandleCycle();
                    }
                    else
                    {
                        alive = false;
                        Thread.Sleep(1000);
                        plc.Connect();
                    }
                }
                catch(Exception ex)
                {
                    if (oldMsg != ex.Message)
                    {
                        oldMsg = ex.Message;
                        this.DebugMsg(plc.GetDeviceName() + oldMsg, InfoLevel.error);
                        this.LogError(plc.GetDeviceName() + oldMsg, ex);
                    }
                    plc.DisConnect();
                }
                Thread.Sleep(300);
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="plc"></param>
        /// <param name="index"></param>
        public void HandleCycle()
        {
            if (plc.IsConnected)
            {
                x1.CheckSignal(plc, plcIndex);
                x2.CheckSignal(plc, plcIndex); 

                this.heartBit = !this.heartBit;
                plc.Write<bool>(Packer.上位机心跳, this.heartBit);
            }
        }

        private void MyEventHandle(PlcSignalPara para)
        {
            new Thread(new ParameterizedThreadStart(Thread_HandleEvent)) { IsBackground = true }.Start(para);
        }

        private void Thread_HandleEvent(object obj)
        {
            try
            {
                PlcSignalPara p = (PlcSignalPara)obj;

                //debug.DebugMsg(now.ToString() + "开始！");
                //Thread.Sleep(3000);
                if (p.eventId == EventId.包装完成)
                {
                    bool bRead;
                    //读取袋批次及编号
                    saveddataBag bag = new saveddataBag();
                    bag.id = 0;
                    bag.batchNo = p.plc.Read<string>(Packer.当前包装批次, out bRead);
                    bag.count = p.plc.Read<string>(Packer.当前包装计数, out bRead).TrimStart(' ');
                    bag.productMark = p.plc.Read<string>(Packer.当前包装尺寸, out bRead);
                    PIMS.DBModel.orderformhistory batch = SqlSugarHelper.Query<PIMS.DBModel.orderformhistory>(
                                                                                        String.Format("batchNo='{0}' and packager='{1}'",
                                                                                            bag.batchNo, sPack), "id desc");
                    if (batch != null)
                    {
                        bag.grade = batch.grade/*.Split('|')[1]*/;
                        bag.productName = batch.productName/*.Split('|')[1]*/;
                        bag.packager = batch.packager;
                        bag.workOrder = batch.workOrder;
                        bag.weight = "10.0";
                        bag.uid = bag.batchNo + bag.count;
                        bag.productTime = DateTime.Now;
                        bag.reserved2 = batch.reserved1;
                        SqlSugarHelper.InsertRecord(bag);
                    }
                }
                if (p.eventId == EventId.请求新批次信息)
                {
                    DateTime now = DateTime.Now;
                    debug.DebugMsg(String.Format("* PLC编号={0},触发事件ID={1}", p.plcIndex, p.eventId.ToString()));
                    bool bRet = false;
                    string sBatch = Encoding.Default.GetString(p.plc.Read<byte[]>(Packer.批次信息, out bRet));
                    string sFlag = sBatch.Substring(1, 1);
                    if (!sBatch.Equals(""))
                    {
                        if (bRet)
                        {
                            #region 查询批次 批次信息=大料/小料标志+批次代号
                            debug.DebugMsg(now.ToString() + String.Format("查询批次{0}！", sBatch));

                            DBModel.orderformcurrent batch = ORM.SqlSugarHelperExternal.Query<DBModel.orderformcurrent>(
                                                                String.Format(" reserved14='{0}' and packager='{1}'",
                                                                sBatch.Substring(2, 2), "自动包装"+sPack), "Id");

                            DBModel.orderformhistory batchhistory = ORM.SqlSugarHelperExternal.Query<DBModel.orderformhistory>(
                                                                String.Format(" reserved14='{0}' and packager='{1}'",
                                                                sBatch.Substring(2, 2), "自动包装" + sPack), "Id desc");
                            #endregion
                            if (null != batch)
                            {
                                string sPre = string.Format("TP{0}", (Convert.ToInt32(sPack)+3) + DateTime.Now.ToString("yyMMdd"));
                                //string sfex = string.Format(",{0},{1}", sBatch, batch.batchNo);
                                if (sFlag.Equals("1"))
                                {
                                    p.plc.Write<string>(Packer.大料批次, batch.batchNo);
                                    p.plc.Write<string>(Packer.大料料况, batch.productName/*.Split('|')[1]*/);
                                    p.plc.Write<string>(Packer.大料尺寸, batch.productMark/*.Split('|')[1]*/);
                                    p.plc.Write<string>(Packer.大料前缀, sPre);
                                    p.plc.Write<string>(Packer.大料后缀, string.Format(",{0},{1}", sBatch.Substring(0,2) + batch.reserved3, batch.batchNo));
                                    //p.plc.Write<string>(9, batch.reserved3);

                                    p.plc.Write<string>(Packer.投料年份, DateTime.Now.Year.ToString());
                                    p.plc.Write<bool>(Packer.上位机写入完成反馈, true);
                                }
                                else if(sFlag.Equals("2"))
                                {
                                    p.plc.Write<string>(Packer.小料批次, batch.batchNo);
                                    p.plc.Write<string>(Packer.小料料况, batch.reserved9/*.Split('|')[1]*/);
                                    p.plc.Write<string>(Packer.小料尺寸, batch.reserved10/*.Split('|')[1]*/);
                                    p.plc.Write<string>(Packer.小料前缀, sPre);
                                    p.plc.Write<string>(Packer.小料后缀, string.Format(",{0},{1}", sBatch.Substring(0, 2) + batch.reserved12, batch.batchNo));
                                    //p.plc.Write<string>(14, batch.reserved3);

                                    p.plc.Write<string>(Packer.投料年份, DateTime.Now.Year.ToString());
                                    p.plc.Write<bool>(Packer.上位机写入完成反馈, true);
                                }
                            }
                            else if (batchhistory != null)
                            {
                                string sPre = string.Format("TP{0}", (Convert.ToInt32(sPack) + 3) + DateTime.Now.ToString("yyMMdd"));
                                //string sfex = string.Format(",{0},{1}", sBatch, batch.batchNo);
                                if (sFlag.Equals("1"))
                                {
                                    p.plc.Write<string>(Packer.大料批次, batchhistory.batchNo);
                                    p.plc.Write<string>(Packer.大料料况, batchhistory.productName/*.Split('|')[1]*/);
                                    p.plc.Write<string>(Packer.大料尺寸, batchhistory.productMark/*.Split('|')[1]*/);
                                    p.plc.Write<string>(Packer.大料前缀, sPre);
                                    p.plc.Write<string>(Packer.大料后缀, string.Format(",{0},{1}", sBatch.Substring(0, 2) + batchhistory.reserved3, batchhistory.batchNo));
                                    //p.plc.Write<string>(9, batch.reserved3);

                                    p.plc.Write<string>(Packer.投料年份, DateTime.Now.Year.ToString());
                                    p.plc.Write<bool>(Packer.上位机写入完成反馈, true);
                                }
                                else if (sFlag.Equals("2"))
                                {
                                    p.plc.Write<string>(Packer.小料批次, batchhistory.batchNo);
                                    p.plc.Write<string>(Packer.小料料况, batchhistory.reserved9/*.Split('|')[1]*/);
                                    p.plc.Write<string>(Packer.小料尺寸, batchhistory.reserved10/*.Split('|')[1]*/);
                                    p.plc.Write<string>(Packer.小料前缀, sPre);
                                    p.plc.Write<string>(Packer.小料后缀, string.Format(",{0},{1}", sBatch.Substring(0, 2) + batchhistory.reserved12, batchhistory.batchNo));
                                    //p.plc.Write<string>(14, batch.reserved3);

                                    p.plc.Write<string>(Packer.投料年份, DateTime.Now.Year.ToString());
                                    p.plc.Write<bool>(Packer.上位机写入完成反馈, true);
                                }
                            }
                            else
                                debug.DebugMsg(now.ToString() + "未查到批次！");
                        }
                        else
                            debug.DebugMsg(now.ToString() + "读取批次代号失败！");
                    }
                    else
                    {
                        debug.DebugMsg(now.ToString() + String.Format("批次代号为空，请检查！！！", sBatch));
                    }
                    debug.DebugMsg(now.ToString() + "结束！");
                }
                bool result;
            }
            catch (Exception ex)
            {
                log.Error("", ex);
                debug.DebugMsg(ex.Message, InfoLevel.error);
            }
        }

    }
}
